package org.vdab.projects.tasks.client.gui.widgets;

import org.vdab.projects.tasks.client.util.DelayedList;
import org.vdab.projects.tasks.client.util.ICommand;
import org.vdab.projects.tasks.client.util.MessageGuard;
import org.vdab.projects.tasks.shared.entities.IBaseEntity;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;

public class EntityListBoxWidget<E extends IBaseEntity<?>> extends Composite implements ChangeHandler, HasChangeHandlers {

	private static EntityListBoxWidgetUiBinder uiBinder = GWT
			.create(EntityListBoxWidgetUiBinder.class);

	interface EntityListBoxWidgetUiBinder extends UiBinder<Widget, EntityListBoxWidget<?>> {
	}
	
	@UiField
	ListBox listBox;
		
	private DelayedList<E> entities;
	
	public EntityListBoxWidget(DelayedList<E> boundedList) throws Exception {
		initWidget(uiBinder.createAndBindUi(this));
	
		if(boundedList==null){
			MessageGuard.Log("boundList in EntityListBox may not be NULL");
		}
		
		entities = boundedList;
				
		this.listBox.addChangeHandler(this);
		
		entities.onLoadedDo(new ICommand<E>() {
			public void execute(E entity) throws Exception {
				if(entity==null){
					MessageGuard.Log("entity was NULL in whenEntityLoaded of EntityListBox");
				}else{
					MessageGuard.Log("onLoadedDo() of EntityListBox, with "+ entity.getDisplayText());
					add(entity);
				}
			}
		});
	}
	
	//Consider making a list of it, so multiple commands can be added (but requires mechanism to remove them also)
	//Or even consider making an event for it
	ICommand<E> whenSelectedIndexChange;

	//It made more sense to implement this functionality on DelayedList itself 
	//ICommand<E> whenFirstEntityLoaded;
	
	public void setOnChange(ICommand<E> whenSelectedIndexChange){
		this.whenSelectedIndexChange = whenSelectedIndexChange;
	}
	
//	public void setOnFirstEntityLoaded(ICommand<E> whenFirstEntityLoaded){
//		this.whenFirstEntityLoaded = whenFirstEntityLoaded;
//	}

	@Override
	public void onChange(ChangeEvent event) {
		if(this.whenSelectedIndexChange!=null){
			try {
				this.whenSelectedIndexChange.execute(getSelectedEntity());
			} catch (Exception e) {
				MessageGuard.Log(e.getLocalizedMessage());
			}
		}		
	}
	
	public E getSelectedEntity(){
		return this.entities.getByKey(this.listBox.getValue(this.listBox.getSelectedIndex()));
	}
	
	@SuppressWarnings("unused")
	private void update(E entity) {
		for(int i = 0; i< listBox.getItemCount(); i++){
			if(listBox.getValue(i)==entity.getKey()){
				listBox.setItemText(i, entity.getDisplayText());
			}
		}		
	};	
	
	private void add(E entity) throws Exception {
//		if(this.whenFirstEntityLoaded!=null && this.listBox.getItemCount()==0){
//			this.whenFirstEntityLoaded.execute(entity);
//		}
		this.listBox.addItem(entity.getDisplayText(), entity.getKey());
	}

	@Override
	public HandlerRegistration addChangeHandler(ChangeHandler handler) {
		return this.listBox.addChangeHandler(handler);
	}

}
